#pragma once
#include<cstdio>
#include <cerrno>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <iostream>
#include <string>
#define Read O_RDONLY
#define Write O_WRONLY
#define Size 128
const std::string fifo_path = "./myfifo";
#define DefacultyFd -1
#define Server 1
#define User 2
class NamedPipe
{
private:
    bool OpenNamedPipe(int mode)
    {
        _fd = open(_fifo_name.c_str(), mode);
        if (_fd < 0)
            return false;
        return true;
    }

public:
    NamedPipe(const std::string fifo_name, int who)
        : _fifo_name(fifo_name), _id(who)
    {
        // 如果是User只是初始化管道路径和身份
        // 如果是Server才创建管道
        if (_id == Server)
        {
            int ret = mkfifo(_fifo_name.c_str(), 0666);
            if (ret != 0)
            {
                perror("mkfifo");
            }
            std::cout << "Server create named pipe" << std::endl;
        }
    }
    bool OpenForRead()
    {
        return OpenNamedPipe(Read);
    }
    bool OpenForWrite()
    {
        return OpenNamedPipe(Write);
    }
    int ReadPipe(std::string *out)
    {
        char buffer[Size];
        int n = read(_fd, buffer, sizeof(buffer));
        if (n > 0)
        {
            buffer[n] = '\0';
            *out = buffer;
        }
        return n;
    }
    int WritePipe(const std::string &in)
    {
        int n = write(_fd, in.c_str(), in.size());
        return n;
    }
    ~NamedPipe()
    {
        if (_id == Server)
        {
            int ret = unlink(_fifo_name.c_str());
            if (ret != 0)
            {
                perror("unlink");
            }
            std::cout << "Server clean named pipe" << std::endl;
        }
        // 不同进程析构，关闭不同文件描述符
        if (_fd != -1)
            close(_fd);
    }

private:
    const std::string _fifo_name; // 管道路径
    int _id;                      // 身份
    int _fd = DefacultyFd;        // 打开文件后返回的文件描述符
};